home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX401 / HDX.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  41.7 KB  |  1,749 lines

  1. /* hdx.c */
  2.  
  3. /*
  4.  * Atari Hard Disk Installation Utility
  5.  * Copyright 1988 Atari Corp.
  6.  *
  7.  * Associated files
  8.  *    hdx.rsc        resource file
  9.  *    wincap        hard disk database (text file)
  10.  *
  11.  *    hdx.h        object tree definitions
  12.  *    defs.h        constant definitions
  13.  *    part.h        ST structure definitions
  14.  *    ipart.h        IBM structure definitions
  15.  *
  16.  *    hdx.c        top level, user interface (this file)
  17.  *    epart.c        edit partition sizes
  18.  *    fmt.c        disk formatting
  19.  *    part.c        partition reading/writing
  20.  *    sect.c        sector reading, writing, zeroing
  21.  *    string.c    string functions (matching, concat, ...)
  22.  *    assist.c    markbad(), zero()
  23.  *    wincap.c    hard disk parameter / partition size database
  24.  *    st.c        random ST functions (delay, reboot, ...)
  25.  *
  26.  *----
  27.  * 11-May-1988    ml.    Cleaned up the memory management in the program
  28.  *            (ie. for all files).  Memory chunks which are for
  29.  *            sure will be < 32k is allocated using malloc(),
  30.  *            whereas chunks >= 32k is allocated using Malloc().
  31.  *            When using malloc(), you will get the 'Stack Over-
  32.  *            flow message if you are in Supervisor mode and 
  33.  *            you have your own supervisor stack.  To get around
  34.  *            this, have to use mymalloc() (in mymalloc.s).
  35.  * 15-Mar-1988    ml.    Changed interface to Markbad.
  36.  * 11-Jan-1988    ml.    Modified dialogue boxes.
  37.  * 07-Dec-1987    ml.    Started to add in concept of Bad Sector List.
  38.  * ??-Oct-1987  ml.    Partition and Disk type menu now has 15 entries 
  39.  *            instead of 16.
  40.  * 30-Sep-1987    ml.    Inherited 'this' from Landon Dyer.
  41.  * 24-Mar-1986 lmd    Released to software test.
  42.  * 15-Mar-1986 lmd    Hacked up from earlier version by Jim Tittsler.
  43.  * 8-Nov-1988  jye. change and add some codes so that can be used for extended
  44.  *                    and big partition.
  45.  * 13-Jun-1989 jye. Change and add some codes so that HDX can be deal with
  46.  *                    acsi and scsi drives.
  47.  * 22-Jan-1990 jye. Change the HDX so that we don't have to put a informations
  48.  *                    of a drive into the Wincap file.
  49.  * 13-Mar-1990 jye. change the HDX to a genetic one so that the user don't
  50.  *                    need know what kind of drive.
  51.  * 20-Jul-1990 jye. change the interface about the unit select. In the new 
  52.  *                    interface, user tells the type of drive is acsi or scsi,
  53.  *                    then selects unit.
  54.  * 01-Aug-1990 jye. Change hard disk size request from mdsence to readcap.
  55.  * 25-Jul-1991 jye. Change the Hdx so that can be used for IDE-AT drive.
  56.  *
  57.  */
  58.  
  59. #include "obdefs.h"
  60. #include "gemdefs.h"
  61. #include "osbind.h"
  62. #include "mydefs.h"
  63. #include "part.h"
  64. #include "bsl.h"
  65. #include "hdx.h"
  66. #include "ipart.h"
  67. #include "addr.h"
  68. #include "error.h"
  69.  
  70. #define MFM 17
  71.  
  72. extern char sbuf[];
  73. extern int rebootp;
  74. extern long gbslsiz();
  75. extern long get3bytes();
  76. extern long get4bytes();
  77. extern long bslsiz;
  78. extern BYTE *bsl;
  79. extern int uplim;            /* the number of partitions */
  80. extern long sptrk;
  81. extern long spcyl;
  82. extern int ibmpart;
  83. extern int yesscan;
  84. extern long disksiz;
  85. extern long ratio;
  86. extern int typedev;
  87. extern int typedrv;
  88. extern int prevnpart;
  89. extern int atexst;        /* set for AT drive exist */
  90.  
  91. /* Globals */
  92. int rebootp = 0;    /* 1: must reboot (not return to desktop) */
  93. int tformat;            /* TRUE: just formatted disk */
  94. int running;        /* 1: continue evnt_multi() loop */
  95. char sbuf[512];        /* error message buffer */
  96. long extsiz;        /* the size of extened partition */
  97. long ostack;        /* old stack pointer */
  98. int toibm;            /* the flag of partition to ibm format */
  99. int ibm2st;            /* the flag for IBM partition to ST */
  100. long bps;            /* bytes per sector */
  101. int npart;            /* number of partition */
  102. int ext;            /* the index of extended partition */
  103. int extend;            /* the index of end extended partition */
  104. int showmany;        /* the flag that show the too much device alert box */
  105. char ttscsi;        /* SCSI hard disk drive */
  106. int noacsi;            /* set for no ACSI dirve in the system */
  107. int needscan;        /* TRUE: if info in the LOGMAP update */
  108. int noinfo;            /* 1: no informations in the wincap */
  109. int athead;            /* the # of data heads on the AT drive */
  110. int atcyl;            /* the # of cylinders on the AT drive */
  111. int atspt;            /* the # of sectors per track on the AT drive */
  112.  
  113. /*  Logical-to-dev+partition mapping table. */
  114. extern int nlogdevs;        /* #logical devs found */
  115. extern LOGMAP logmap[];        /* logical dev map */
  116. extern int livedevs[];        /* live physical dev flag */
  117. extern char cachexst;        /* 0: no cache. 1: with cache */
  118.  
  119. /* Partition related variables */
  120. long mxpsiz = MAXPSIZ;
  121.  
  122. /* AES (windows and messages) related variables */
  123. int gl_hchar;        /* height of system font (pixels) */
  124. int gl_wchar;        /* width of system font (pixels) */
  125. int gl_wbox;        /* width of box able to hold system font */
  126. int gl_hbox;        /* height of box able to hold system font */
  127.  
  128. int phys_handle;    /* physical workstation handle */
  129. int handle;        /* virtual workstation handle */
  130. int wi_handle;        /* window handle */
  131.  
  132. int formw, formh, sx, sy, lx, ly;    /* dialogue box dimensions */
  133. int xdesk, ydesk, hdesk, wdesk;        /* window X, Y, width, height */
  134. int xwork, ywork, hwork, wwork;        /* desktop and work areas */
  135.  
  136. int msgbuff[8];        /* event message buffer */
  137. int keycode;        /* keycode returned by event-keyboard */
  138. int mx, my;        /* mouse x and y pos. */
  139. int butdown;        /* button state tested for, UP/DOWN */
  140. int ret;        /* dummy return variable */
  141. int pnf;        /* 1: partition or format; 0: zero or markbad */
  142. int hidden;        /* current state of cursor */
  143. int contrl[12];
  144. int intin[128];
  145. int ptsin[128];
  146. int intout[128];
  147. int ptsout[128];    /* storage wasted for idiotic bindings */
  148. int work_in[11];    /* Input to GSX parameter array */
  149. int work_out[57];    /* Output from GSX parameter array */
  150. int pxyarray[10];    /* input point array */
  151. int blitxst;        /* the flag for check the BLiTTER */
  152.  
  153. /*
  154.  * Top level;
  155.  * we get control from the desktop.
  156.  */
  157. main()
  158. {
  159.     pnf = 0;        /* set the flag to it isn't partition yet */
  160.     appl_init();
  161.     phys_handle=graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
  162.     wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
  163.     open_vwork();
  164.     wi_handle=wind_create(0x0040&0x0080, xdesk, ydesk, wdesk, hdesk);
  165.  
  166.     hidden = FALSE;
  167.     butdown = TRUE;
  168.  
  169.     /* doing a checking see if the cache in the system */
  170.     cachexst = (char) chkcache();
  171.  
  172.     /* check the existence of the BLiTTER */
  173.     blitxst = chkblit();
  174.  
  175.     if (!rsrc_load(RESOURCEFILE)) {
  176.     errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  177.     goto punt;
  178.     }
  179.  
  180.     
  181.     /* Get all addresses of dialogues from resource file */
  182.     if (getalladdr() != OK) {
  183.     errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  184.     goto punt;
  185.     }
  186.  
  187.  
  188.     /*
  189.      * Get maximum partition size from
  190.      * wincap "@@" entry.
  191.      */
  192.     /*
  193.     if (wgetent("Parameters", "@@") == OK) {
  194.     if (wgetnum("ms", &mxpsiz) != OK)
  195.         mxpsiz = MAXPSIZ;
  196.     } else {
  197.         goto punt;
  198.     }
  199.     */
  200.  
  201.     needscan = TRUE;
  202.  
  203. redomul:
  204.     ARROW_MOUSE;
  205.  
  206.     /* display menu bar */
  207.     menu_bar(menuobj, 1);
  208.  
  209.     running = TRUE;
  210.     while (running) {
  211.         domulti();
  212.     }
  213.  
  214.     /*
  215.      * If nothing has been done to the hard disks
  216.      * then just get out, back to the desktop.
  217.      * Otherwise reboot the system.
  218.      */
  219.     menu_bar(menuobj, 0);        /* erase menu bar */
  220.  
  221. punt:
  222.     /*
  223.      * If we have to reboot,
  224.      * tell the user and then do it.
  225.      *
  226.      */
  227.     if (rebootp) {
  228.         if (form_alert(2, autoboot) == 1)    {
  229.             reboot();
  230.         } else {
  231.             goto redomul;
  232.         }
  233.     }
  234.  
  235.     wind_delete(wi_handle);
  236.     v_clsvwk(handle);
  237.     appl_exit();
  238. }
  239.  
  240.  
  241. /*
  242.  * Get a single event, process it, and return.
  243.  *
  244.  */
  245. domulti(){
  246.     int event;
  247.     
  248.     event = evnt_multi(MU_MESAG,
  249.             1,1,butdown,
  250.             0,0,0,0,0,
  251.             0,0,0,0,0,
  252.             msgbuff,0,0,&mx,&my,&ret,&ret,&keycode,&ret);
  253.  
  254.     if (event & MU_MESAG) {
  255.         wind_update(TRUE);
  256.     switch (msgbuff[0]) {
  257.         case WM_REDRAW:
  258.         do_redraw(msgbuff[4],msgbuff[5],msgbuff[6],msgbuff[7]);
  259.         break;
  260.  
  261.         case MN_SELECTED:
  262.             BEE_MOUSE;
  263.         switch(msgbuff[3]) {
  264.             case MNDISK:
  265.             switch (msgbuff[4]) {
  266.                 case DIFORM:
  267.                     if ((needscan) && (rescan(0,0) == ERROR))    {
  268.                         break;    /* don't report medium changed */
  269.                     }
  270.                     tformat = TRUE;
  271.                     needscan = FALSE;
  272.                     dodiform();
  273.                     tformat = FALSE;
  274.                     break;
  275.                 case DIPART:
  276.                     if ((needscan)&&(rescan(0,0) == ERROR))    {
  277.                         break;    /* don't report medium changed */
  278.                     }
  279.                     needscan = FALSE;
  280.                     dodipart(-1, NULL, NULL);
  281.                     break;
  282.                 case DIZERO:
  283.                     if (pnf)    {
  284.                         err(needboot);
  285.                     } else {
  286.                         if ((needscan)&&(rescan(0,1) == ERROR))    {
  287.                             break;    /* don't report medium changed */
  288.                         }
  289.                         needscan = FALSE;
  290.                         dodizero();
  291.                     }
  292.                     break;
  293.                 case DIMARK:
  294.                     if (pnf)    {
  295.                         err(needboot);
  296.                     } else {
  297.                         if ((needscan)&&(rescan(0,1) == ERROR))    {
  298.                             break;    /* don't report medium changed */
  299.                         }
  300.                         needscan = FALSE;
  301.                         dodimark();
  302.                     }
  303.                     break;
  304.                 case DISHIP:
  305.                     if ((needscan)&&(rescan(0,0) == ERROR))    {
  306.                         break;    /* don't report medium changed */
  307.                     }
  308.                     needscan = FALSE;
  309.                     dodiship();
  310.                     break;
  311.                 default:        break;
  312.             }
  313.             break;
  314.  
  315.             case MNFILE:
  316.             switch (msgbuff[4]) {
  317.                 case FIQUIT:
  318.                 running = 0;
  319.                 break;
  320.  
  321.                 default:
  322.                 break;
  323.             }
  324.             break;
  325.             
  326.             case MNDESK:
  327.             if(msgbuff[4] == DEABOUT) {
  328.                 strcpy(abtdial[ABVERSN].ob_spec, "Version 4.01");
  329.                  abtdial[ABOK].ob_state = NORMAL;
  330.                 execform(abtdial);
  331.             }
  332.             break;        /* "cannot happen" */
  333.         }
  334.  
  335.         menu_tnormal(menuobj, msgbuff[3], 1);    /* back to normal */
  336.             ARROW_MOUSE;
  337.         break;
  338.         
  339.         case WM_NEWTOP:
  340.         case WM_TOPPED:
  341.         wind_set(wi_handle, WF_TOP, 0, 0, 0, 0);
  342.         break;
  343.  
  344.         case WM_CLOSED:
  345.         running = FALSE;
  346.         break;
  347.  
  348.         default:
  349.         break;
  350.     }
  351.     wind_update(FALSE);
  352.     }
  353. }
  354.  
  355.  
  356. /*
  357.  * Default partition name (no "pt" entry).
  358.  */
  359. #define    DEF_PARTNAME    "4-6-10"
  360.  
  361.  
  362. /*
  363.  * Map from button in format dial.
  364.  */
  365. int pfmt[] = {
  366.     PFMT0, PFMT1, PFMT2, PFMT3,
  367.     PFMT4, PFMT5, PFMT6, PFMT7,
  368.     PFMT8, PFMT9, PFMT10, PFMT11,
  369.     PFMT12, PFMT13, PFMT14, PFMT15
  370. };
  371.  
  372.  
  373. /*
  374.  * Handle [FORMAT] item.
  375.  *
  376.  */
  377. dodiform()
  378. {
  379.   extern char bootstop;
  380.   extern char bootend;
  381.   int dev, v, w, i, br;
  382.   int modesel;            /* flag for mode select */
  383.   long cnt, hdsiz;
  384.   char *s, *d, *wgetstr();
  385.   char buf[10], bs[512], sendata[32];
  386.   char pnam[128];
  387.   char *seldev = "ACSI unit 0", *id = "XXXXX";
  388.   char *seldv =  "IDE  unit 0";
  389.   HINFO hinfo;
  390.   char devnames[NAMSIZ];    /* device type name buffer */
  391.   long nbad;
  392.   extern long gbslsiz(), nument(), dsmarkbad();
  393.   long pattern, temp;
  394.   long longrandom();
  395.   char pr_id[10];    /* partition scheme id */
  396.   int mask = 0x0001;
  397.   int set, scsidrv, bsiz, other = 0;
  398.   
  399.   /*
  400.    * Throw up generic formatting/partition warning,
  401.    * then get physical dev they want to clobber.
  402.    */
  403.   yesscan = 0;
  404.   noinfo = 0;
  405.   for (i = 0; i < NAMSIZ; i++)
  406.       devnames[i] = "\0";
  407.   fwarning[FWARNCN].ob_state = NORMAL;
  408.   fwarning[FWARNOK].ob_state = NORMAL;
  409.   if (execform(fwarning) != FWARNOK) return BAILOUT;
  410.  
  411.   if ((dev = gphysdev()) < 0) {
  412.       return BAILOUT;
  413.   }
  414.   strcpy(id, "mn");
  415.   br = 0;
  416.  
  417.   /* display doing SCSI massage */
  418.  
  419.   if (dev > 7)  {    /* do the SCSI drive */
  420.       noinfo = 1;
  421.       goto stfm;
  422.   }
  423.   
  424.   inqfmt:
  425.   /* Get all available disk types from wincap 'mn' entries */  
  426.   wallents(devnames, id);
  427.   if (!*devnames)     {
  428.       noinfo = 1;
  429.       goto stfm;
  430.   }
  431.   
  432.   /* Shove format name text into buttons */
  433.   for (i = 0, s = devnames; i < 14 && *s; ++i) {
  434.       dsknames[pfmt[i]].ob_type = G_BUTTON;    /* button */
  435.       dsknames[pfmt[i]].ob_spec = (long)s;
  436.       dsknames[pfmt[i]].ob_state = NORMAL;
  437.       dsknames[pfmt[i]].ob_flags = SELECTABLE | RBUTTON;
  438.       while (*s++)
  439.     ;
  440.   }
  441.   other = i;                            /* the other button */
  442.   dsknames[pfmt[i]].ob_type = G_BUTTON;    /* button */
  443.   dsknames[pfmt[i]].ob_spec = "OTHER";
  444.   dsknames[pfmt[i]].ob_state = NORMAL;
  445.   dsknames[pfmt[i]].ob_flags = SELECTABLE | RBUTTON;
  446.   i++;
  447.  
  448.   /* rest of buttons are invisible and untouchable */
  449.   for (; i < 16; ++i) {
  450.       dsknames[pfmt[i]].ob_type = G_IBOX;    /* invisible box */
  451.       dsknames[pfmt[i]].ob_spec = 0;        /* no thickness */
  452.       dsknames[pfmt[i]].ob_state = DISABLED;    /* nobody home */
  453.       dsknames[pfmt[i]].ob_flags = NONE;        /* disabled */
  454.   }
  455.   
  456.   /* clean up rest of the form and throw it up */
  457.   dsknames[PFOK].ob_state = NORMAL;
  458.   dsknames[PFCN].ob_state = NORMAL;
  459.   if (execform(dsknames) != PFOK)
  460.     return BAILOUT;
  461.   
  462.   /* search for format they picked */
  463.   for (i = 0; i < 18; ++i)
  464.     if (dsknames[pfmt[i]].ob_state & SELECTED)
  465.       break;
  466.   if (i >= 18) {        /* nothing picked */
  467.       return BAILOUT;
  468.   } else if (other == i)    {  /* the OTHER button was selected */
  469.         noinfo = 1;
  470.       goto stfm;
  471.   }
  472.   
  473.     if ((!br) && (dev < 8))        {
  474.           if (wgetent(dsknames[pfmt[i]].ob_spec, "mn") == ERROR)    {
  475.             nofmt[NOSCHFMT].ob_spec = dsknames[pfmt[i]].ob_spec;
  476.             nofmt[NOSCHFMT].ob_state = NORMAL;
  477.             execform(nofmt, 0);
  478.             return ERROR;
  479.         }
  480.         if ((s = wgetstr("br")) != NULL)    {
  481.             strcpy(id, s);
  482.             br = 1;            /* processing the branch */
  483.             goto inqfmt;    /* start over */
  484.         }
  485.     }
  486.  
  487. stfm:
  488.     modesel = 1;
  489.   if (gfparm(dev, noinfo, &modesel, &hinfo, dsknames[pfmt[i]].ob_spec,id)!= 0) {
  490.       return ERROR;
  491.   }
  492.   
  493.   /* get data pattern to test the disk */
  494.   if (wgetnum("dp", &pattern) != OK) {
  495.       pattern = longrandom();  /* can't find pattern from wincap, make one */
  496.   } else {
  497.       temp = pattern;
  498.       pattern <<= 16;    /* shift pattern to hi word */
  499.       pattern |= temp;
  500.   }
  501.  
  502.   if (dev > 15)    { /* IDE-AT drive */
  503.       br = dev - 16;
  504.   } else {            /* it is a scsi or acsi drive */
  505.       br = (dev > 7) ? (dev-8) : (dev);    /* minus 8 for the scsi drive number */
  506.   }
  507.   /*
  508.    * One last chance to bail out.
  509.    */
  510.   *seldev = 'A';
  511.   if (dev > 15)    { /* it is a IDE-AT drive */
  512.       seldev = seldv;
  513.   } else if (dev > 7)    { /* it is a SCSI drive */
  514.           *seldev = 'S';
  515.   }
  516.   *(seldev + 10) = br + '0';
  517.   (fmtfnl[FUNIT].ob_spec)->te_ptext = seldev;
  518.   fmtfnl[FMTYES].ob_state = NORMAL;
  519.   fmtfnl[FMTNO].ob_state = NORMAL;
  520.   if (execform(fmtfnl) != FMTYES) return BAILOUT;
  521.  
  522.   /* For REAL !! */  
  523.   dsplymsg(fmtmsg);
  524.  
  525.   bsl = 0L;
  526.   
  527.   /* Get size of Bad Sector List */
  528.   if ((bslsiz = gbslsiz(dev)) > 0L) {
  529.       /* Allocate memory for existing BSL */
  530.       if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  531.           ret = err(nomemory);
  532.           goto formend;
  533.       }
  534.       
  535.       /* Read in BSL */
  536.       if ((ret = rdbsl(dev)) != OK) {
  537.           /* Create a new BSL if current one is unusable */
  538.           if (creabsl(dev, NEW, 0L) != OK) {
  539.               ret = ERROR;
  540.               goto formend;
  541.           }
  542.       } else {
  543.             /* Remove USER BSL */
  544.             if (creabsl(dev, EXPAND, nument(VENDOR)) != OK) {
  545.                 ret = ERROR;
  546.                 goto formend;
  547.             }
  548.       }
  549.   } else if (bslsiz == 0L || bslsiz == ERROR) {    /* no bsl or read error */
  550.       if (creabsl(dev, NEW, 0L) != OK) {
  551.           ret = ERROR;
  552.           goto formend;
  553.       }
  554.   } else {    /* bslsiz == MDMERR; medium changed error */
  555.       ret = ERROR;
  556.       goto formend;
  557.   }
  558.   
  559.   /*
  560.    * In supervisor mode
  561.    * set disk format parameters
  562.    * and format the disk.
  563.    */
  564.   ostack = Super(NULL);
  565.   delay();
  566.   if (dev > 15)        { /* do the IDE-AT format */
  567.      if ((ret = fmtunt(dev)) != OK)    {
  568.       delay();
  569.         Super(ostack);
  570.       ret = errcode(dev);
  571.       if (tsterr(ret) != OK)
  572.           formaterr(dev);
  573.       ret = ERROR;
  574.     } else {
  575.         if (dev == 16)    {/* it is a master IDE-AT */
  576.             hdsiz = athead*atcyl*atspt; 
  577.         } 
  578.           disksiz = hdsiz;
  579.         delay();
  580.           Super(ostack);
  581.     }
  582.     goto formend;
  583.   }
  584.   if (modesel)    {            /* normal mode select ? */
  585.       v = ms(dev, &hinfo);    /* Yes, do noprmal mode set */
  586.         /* Find formatted capacity of drive */
  587.       hdsiz = (long)hinfo.hi_cc * (long)hinfo.hi_dhc * (long)hinfo.hi_spt;
  588.   }    else if (dev < 8)    {        /* No, do special mode set */
  589.       set = typedev & (mask << dev);
  590.     scsidrv = typedrv & (mask << dev);
  591.     bsiz = ((set) || (scsidrv)) ? (16) : (22);
  592.     for (i = 0; i < 32; i++)
  593.         sendata[i] = 0;
  594.     if ((set) || (scsidrv))    {
  595.           v = mdsense(dev, 4, 0, 32, sendata);
  596.           for (i = 0; i < 32; i++) /* the lenght of sendata */
  597.               if (sendata[i])
  598.                 break;
  599.           if (i == 32)    { /* no infomations returned */
  600.             delay();
  601.             goto jjj;
  602.           }
  603.         hdsiz = get3bytes(sendata+5);
  604.           delay();                    /* kludge delay */
  605.         v = sqms(dev, sendata);
  606.         delay();
  607.         goto kkk;
  608.     }
  609. jjj:
  610.     for (i = 0; i < 32; i++)
  611.         sendata[i] = 0;
  612.       if ((v = mdsense(dev, 0, 0, bsiz, sendata)) == OK)        {
  613.           for (i = 0; i < bsiz; i++)
  614.               if (sendata[i])
  615.                 break;
  616.           if (i == bsiz)    { /* no infomations returned */
  617.             ret = 111;        
  618.             goto kkk;
  619.           }
  620.         hdsiz = get3bytes(sendata+5);
  621.           delay();                    /* kludge delay */
  622.         v = sqms(dev, sendata);
  623.     } else {
  624.           for (i = 0; i < bsiz; i++)
  625.               if (sendata[i])
  626.                 break;
  627.           if (i == bsiz)    { /* no infomations returned */
  628.             ret = 111;        
  629.           }
  630.     }
  631.   }    else {
  632.         if ((v = readcap(dev, 0, (long)0, buf)) == OK)    {
  633.             hdsiz = get4bytes(buf) + 1;
  634.             ret = OK;
  635.         }
  636.   }
  637. kkk:
  638.   disksiz = hdsiz;
  639.   delay();                    /* kludge delay */
  640.   if (v == OK)    {
  641.       v = format(dev, (UWORD)hinfo.hi_in);  /* format */
  642.   }
  643.   delay();                    /* kludge delay */
  644.   Super(ostack);
  645.   
  646.   if (v != 0)  {
  647.       ret = errcode(dev);
  648.       if (tsterr(ret) != OK)
  649.           formaterr(dev);
  650.       ret = ERROR;
  651.       goto formend;
  652.   }
  653.   
  654.   ret = OK;
  655.   rebootp = 1;
  656. formend:
  657.   erasemsg();    /* Erase formatting box */
  658.   if (ret == 111)        /* HDX may not support this drive */
  659.           ret = err(needinfo);
  660.   if (ret < 0) {
  661.       if (bsl > 0) free(bsl);
  662.       return ERROR;
  663.   }
  664.   
  665.   /*------------------------------------------*
  666.    * Markbad the device destructively.          *
  667.    * Bad Sectors found are added to the BSL.  *
  668.    * Write BSL to device.              *
  669.    *------------------------------------------*/
  670.   if ((nbad = dsmarkbad(dev, hdsiz, 1, pattern)) < 0) {
  671.       free(bsl);
  672.       return ERROR;
  673.   }
  674.   if (wrbsl(dev) != OK) {
  675.       free(bsl);
  676.       return ERROR;
  677.   }
  678.   free(bsl);
  679.  
  680.     
  681.   /*
  682.    * Install boot-stopper in sector image;
  683.    * write root sector to device.
  684.    * 6-13-88  Setting of soft format parameters in root sector sets
  685.    *        the hard disk size only.
  686.    */
  687.   fillbuf(bs, 512L, 0L);    /* create new root sector */
  688.   sbslparm(bs);            /* set BSL parameters */
  689.   if (modesel)    {
  690.       sfmtparm(bs, &hinfo);
  691.   } else {
  692.       sdisksiz(bs, disksiz);
  693.   }
  694.   for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;)
  695.     *d++ = *s++;
  696.   Protobt(bs, -1L, -1, 1);    /* make root sector executable */
  697.   
  698.   if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  699.       if (tsterr(ret) != OK)
  700.           err(rootwrit);
  701.       return ERROR;
  702.   }
  703.  
  704.   /*
  705.    * Make a copy of the default partition name.
  706.    * Figure out the partition scheme id.
  707.    */
  708.   if (!noinfo)    {
  709.       s = wgetstr("pt");
  710.       strcpy(pnam, s);
  711.   }
  712.   /* ??
  713.   figprid(disksiz, pr_id);
  714.   */
  715.   dodipart(dev, pnam, disksiz);
  716.   return OK;
  717. }
  718.  
  719.  
  720.  
  721. /*
  722.  * Handle [PARTITION] item;
  723.  * if `xdev' is -1, throw up dialog boxes;
  724.  * if `xdev' >= 0, just partition the dev,
  725.  * using `pnam' as the partition type, 
  726.  * and `pr_id' to search for the type.
  727.  *
  728.  */
  729. dodipart(xdev, pnam, hsize)
  730. int xdev;
  731. char *pnam;
  732. long hsize;
  733. {
  734.     int dev, i, ret =OK, fine;
  735.     int choice;
  736.     char *seldev = "ACSI unit 0";
  737.       char *seldv =  "IDE  unit 0";
  738.     char *s;
  739.     char bs[512];
  740.     PART *pinfo;
  741.     int tem1, tem2;
  742.     long disksiz;
  743.     extern long getdsiz();
  744.     int mask = 0x0001;
  745.  
  746.     if (xdev < 0) {
  747.     /*
  748.      * Throw up warning saying that partition is dangerous;
  749.      * then get physical dev they want to clobber.
  750.      */
  751.     pwarning[PWARNCN].ob_state = NORMAL;
  752.     pwarning[PWARNOK].ob_state = NORMAL;
  753.     if (execform(pwarning) != PWARNOK) return BAILOUT;
  754.     tformat = FALSE;
  755.     if ((dev = gphysdev()) < 0) {
  756.         return BAILOUT;
  757.     }
  758.     /*
  759.      * Let the user edit/pick partitions.
  760.      */
  761.     fine = 0;
  762.     while (!fine) {
  763.         if (sfigpart(bs, dev, (PART *)&pinfo) != OK)    {
  764.             if (pinfo > 0)    Mfree(pinfo);
  765.             return BAILOUT;
  766.         }
  767.         if ((ret = chkpart(dev, pinfo)) != OK) {
  768.             if (ret < 0)    {    /* size too big */
  769.                 err(nexsmem);
  770.             } else {    /* some other errors  */
  771.                 if (pinfo > 0)    Mfree(pinfo);
  772.                 return BAILOUT;
  773.             }
  774.         } else {
  775.             fine = 1;
  776.         }
  777.     }
  778.  
  779.       fine = dev;            /* default for the acsi unit */
  780.     *seldev = 'A';
  781.       if (dev > 15)    { /* it is a IDE-AT drive */
  782.         fine = dev - 16;
  783.         seldev = seldv;
  784.     } else if (dev > 7)     {    /* minus 8 for the scsi drive number */
  785.         fine = dev - 8;
  786.         *seldev = 'S';
  787.     }
  788.     *(seldev + 10) = fine + '0';
  789.  
  790.     /* Last chance to bail out */
  791.     (partfnl[PUNIT].ob_spec)->te_ptext = seldev;
  792.     partfnl[PARTYES].ob_state = NORMAL;
  793.     partfnl[PARTNO].ob_state = NORMAL;
  794.     if (execform(partfnl) != PARTYES)    {
  795.         if (pinfo > 0)    Mfree(pinfo);
  796.         return BAILOUT;
  797.     }
  798.  
  799.     } else {
  800.         /* ??
  801.         if ((!noinfo) && (!ttscsi) && (wgetent(pnam, pr_id) != OK)) {
  802.             nopart[NOSCHPOK].ob_state = NORMAL;
  803.             (nopart[NOSCHPR].ob_spec)->te_ptext = pnam;
  804.             execform(nopart);
  805.             return ERROR;
  806.         }
  807.         */
  808.         npart = 4;
  809.         ext = NO_EXT;    /* set the extended partition flag to not exists */
  810.         dev = xdev;
  811.         if ((pinfo = (PART *)Malloc((long)sizeof(PART)*npart)) <= 0)    {
  812.             err(nomemory);
  813.             if (pinfo > 0)    Mfree(pinfo);
  814.             return ERROR;
  815.         }
  816.         inipart(pinfo, npart);
  817.         npart = 0;
  818.         setpart(pinfo, pnam, hsize);
  819.         /* ??
  820.         if (ttscsi)        {     SCSI bus drive 
  821.             setpart(pinfo, hsize);
  822.         } else {             regular drvie 
  823.             for (i = 0; i < 4; ++i)
  824.                 fillpart(i, &pinfo[i]);
  825.         }
  826.         */
  827.     }
  828.  
  829.     /* For REAL!! */
  830.     dsplymsg(partmsg);
  831.     
  832.     bsl = 0L;
  833.     
  834.     /* Get size of BSL */
  835.     if ((bslsiz = gbslsiz(dev)) > 0L) {
  836.         /* Allocate memory for existing BSL */
  837.         if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  838.             ret = err(nomemory);
  839.             goto partend;
  840.         }
  841.             
  842.         /* Read in BSL */
  843.         if ((ret = rdbsl(dev)) != OK) {
  844.             if (ret == INVALID)
  845.                 err(cruptbsl);
  846.             ret = ERROR;
  847.             goto partend;
  848.         }
  849.     } else if (bslsiz == 0) {
  850.         ret = err(oldfmt);
  851.         goto partend;
  852.     } else if (bslsiz == ERROR) {
  853.         ret = err(rootread);
  854.         goto partend;
  855.     } else {
  856.         ret = ERROR;
  857.         goto partend;
  858.     }
  859.  
  860.     
  861.     /* Lay out partition headers */
  862.     if (spheader(dev, &pinfo[0]) != OK) {
  863.         ret = ERROR;
  864.         goto partend;
  865.     }
  866.     
  867.     if (wrbsl(dev) != OK) {        /* write BSL */
  868.         ret = ERROR;
  869.         goto partend;
  870.     }
  871.  
  872.     /* check and change the structure's id after 'spheader()' */
  873.     changeid(pinfo);
  874.  
  875.     /* Shove partition parms into root sector */
  876.     if ((ret = getroot(dev, bs, (SECTOR)0)) != 0)    {
  877.         if (tsterr(ret) != OK)
  878.             err(rootread);
  879.         ret = ERROR;
  880.         goto partend;
  881.     }
  882.  
  883.     if ((ret = stlayroot(bs, dev, pinfo)) != OK)    {
  884.         goto partend;
  885.     }
  886.     tem1 = npart;            /* save the number of partitions */
  887.     tem2 = ext;                /* save the index of extended partition */
  888.     if (rescan(1,0)) {        /* has to be here because map changed    */
  889.         ret = ERROR;        /* after partitions are moved around,    */
  890.         goto partend;        /* report medium change error.        */
  891.     }
  892.     npart = tem1;
  893.     ext = tem2;
  894.     /* Partition the device with parameters given in pinfo */
  895.     if (stlaybs(dev, &pinfo[0]) != OK)
  896.         ret = ERROR;
  897.     else
  898.         ret = OK;
  899.         
  900.     rebootp = 1;
  901.     /*  add on Jul 2, 90 for removable drive
  902.     if ((typedev & (mask << dev)))             it is a removable drive 
  903.         if (npart <= prevnpart)                 if less or equal than prevous 
  904.             rebootp = 0;                      partition, don't reboot 
  905.     change and add over on Jul 2, 90 for the removable drive on Oct 1, 90
  906.     if ((typedev & (mask << dev)))    {         it is a removable drive 
  907.         for (i = 0; i < 10; i++)     {
  908.             if (!mediach(dev))            
  909.                 break;
  910.             if (i == 10)
  911.                 rebootp = 1;
  912.             else
  913.                 rebootp = 0;
  914.         }
  915.     }
  916.     */
  917.     pnf = 1;        /* set the flag to just doing the partition */
  918. partend:
  919.     if (bsl > 0) free(bsl);
  920.     inipart(pinfo, npart);
  921.     if (pinfo > 0)    Mfree(pinfo);
  922.     erasemsg();
  923.     return (ret);
  924. }
  925.  
  926.  
  927. /*
  928.  * get root sector informations and write them into that sector 
  929.  */
  930.  
  931. stlayroot(bs, dev, part)
  932. char *bs;
  933. int dev;
  934. PART *part;
  935. {
  936.     int i;
  937.     UWORD sum = 0x1234;
  938.     long cnt, disksiz, prvst;
  939.     char *d, *s;
  940.     extern char bootstop;
  941.     extern char bootend;
  942.  
  943.     /* do the prime partition */
  944.     spart(bs, part, 0, &prvst);    /* set ST partition parameters */
  945.     /*
  946.       sfmtparm(bs, &hinfo);
  947.       for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;)
  948.         *d++ = *s++;
  949.     */
  950.     sbslparm(bs);                /* set bsl parameters */
  951.     Protobt(bs, -1L, -1, 1);        /* make root sector executable */
  952.     if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  953.         if (tsterr(ret) != OK)
  954.             err(rootwrit);
  955.         return(ERROR);
  956.     }
  957.     if (ext == NO_EXT)    return OK;        /* no extended partition */
  958.     /* do the extended partitions */
  959.     extsiz = part[ext].p_siz;
  960.     for (i = 4; i < npart; i++)    {
  961.         if (!(part[i].p_flg & P_EXISTS))    {     /* skip if not exists */
  962.             return OK;
  963.         }
  964.         spart(bs, part, i, &prvst);    /* set IBM partition parameters */
  965.         if ((ret = putroot(dev, bs, part[i].p_st)) != OK) {
  966.             if (tsterr(ret) != OK)
  967.                 err(rootwrit);
  968.             return(ERROR);
  969.         }
  970.     }
  971.     return OK;
  972. }
  973.  
  974.  
  975.  
  976.  
  977. /*
  978.  * Put information into the root structure
  979.  */
  980.  
  981. spart(image, pinfo, pnm, prvst)
  982.  
  983. char *image;            /* root sector buffer */
  984. register PART *pinfo;    /* partition information */
  985. int pnm;                /* partition number */
  986. long *prvst;            /* The previous partition start sector */
  987.  
  988. {
  989.     PART *rpart;
  990.     long numcyl;
  991.     int i, j;
  992.  
  993.     if (pnm)     {
  994.         fillbuf(image, 512L, 0L);
  995.     }
  996.     rpart = &((RSECT *)(image + 0x200 - sizeof(RSECT)))->hd_p[0];
  997.     if (pnm < 4)    {
  998.         for (i = 0; i < NPARTS; i++, rpart++)    {
  999.             if (pinfo->p_flg & P_EXISTS)    {
  1000.                 rpart->p_flg = P_EXISTS;
  1001.                 for (j = 0; j < 3; j++)
  1002.                     rpart->p_id[j] = pinfo->p_id[j];
  1003.                 rpart->p_st = pinfo->p_st;
  1004.                 rpart->p_siz = pinfo->p_siz;
  1005.             } else {
  1006.                 rpart->p_flg = 0;
  1007.                 for (j = 0; j < 3; j++)
  1008.                     rpart->p_id[j] = 0;
  1009.                 rpart->p_st = 0L;
  1010.                 rpart->p_siz = 0L;
  1011.             }
  1012.             pinfo++;
  1013.         }
  1014.  
  1015.     } else {    /* pnm => 4 */
  1016.         rpart->p_flg = pinfo[pnm].p_flg;
  1017.         for (j = 0; j < 3; j++)
  1018.             rpart->p_id[j] = pinfo[pnm].p_id[j];
  1019.         rpart->p_st = ROOTSECT;
  1020.         rpart->p_siz = pinfo[pnm].p_siz - ROOTSECT;
  1021.         rpart++;
  1022.         if (((pnm + 1) != npart) && (pinfo[pnm+1].p_flg & P_EXISTS)) { 
  1023.             /* need extened partition */
  1024.             rpart->p_flg = P_EXISTS;
  1025.             rpart->p_id[0] = 'X';
  1026.             rpart->p_id[1] = 'G';
  1027.             rpart->p_id[2] = 'M';
  1028.             rpart->p_siz = pinfo[pnm+1].p_siz;
  1029.             rpart->p_st = (pnm == 4) ? (pinfo[4].p_siz) :
  1030.                                     (pinfo[pnm].p_siz + *prvst);
  1031.             *prvst = rpart->p_st;
  1032.         }
  1033.  
  1034.     }
  1035. }
  1036.  
  1037.  
  1038.  
  1039. /*
  1040.  * Setup partitions on the disk;
  1041.  * write boot sectors and zero FATs and root directories.
  1042.  *
  1043.  */
  1044. stlaybs(physdev, pinfo)
  1045. int physdev;
  1046. register PART *pinfo;
  1047. {
  1048.     int i, ldev, ret;
  1049.     int kindfat;
  1050.     SECTOR data, nsect;
  1051.     char *devno="X";
  1052.     long ndirs;
  1053.     UWORD fatsiz;
  1054.     BOOT *bs;
  1055.     long serialno;
  1056.     extern long longrandom();
  1057.     extern long cell();
  1058.     char *buf;
  1059.     long size;
  1060.  
  1061.     if ((bslsiz = gbslsiz(physdev)) < 0L) {
  1062.         if (bslsiz == ERROR)
  1063.             err(rootread);
  1064.         return ERROR;
  1065.     }
  1066.     /* SCAN_BS: pinfo is for scan() and laybs() use */
  1067.     if (ext != NO_EXT)    sortpart(pinfo, SCAN_BS);    
  1068.  
  1069.     for (i = 0; i < npart; ++i, ++pinfo) {
  1070.         
  1071.         /* don't care if partition does not exist */
  1072.         if (!(pinfo->p_flg & P_EXISTS)) {
  1073.             return OK;
  1074.         }
  1075.  
  1076.  
  1077.     /*
  1078.      * Compute boot sector parameters.
  1079.      */
  1080.         if (pinfo->p_siz > disksiz) {        /* partition >? disk size */
  1081.             *devno = i + '0';
  1082.             (part2big[BGPART].ob_spec)->te_ptext = devno;
  1083.             part2big[BGPARTOK].ob_state = NORMAL;
  1084.             execform(part2big);
  1085.             return ERROR;
  1086.         }
  1087.  
  1088.     /* estimat the bps */
  1089.     /* MAXSECT = 16MB - 8 */
  1090.     bps = cell((pinfo->p_siz-7)*BPS, (long)MAXSECT);
  1091.  
  1092.     /* the real bps */
  1093.     bps = BPS * n2power((UWORD)cell(bps, (long)BPS));
  1094.     ratio = bps / BPS;
  1095.     nsect = pinfo->p_siz / ratio;
  1096.  
  1097.     size = (long)BPS * ratio;
  1098.     if ((buf = (char *)Malloc(size)) <= 0)    {
  1099.         err(nomemory);
  1100.         if (buf > 0) Mfree((long)buf);
  1101.         return ERROR;
  1102.     }
  1103.  
  1104.     /*
  1105.      * Install entries in boot sector image;
  1106.      * force sector checksum to zero (non-executable);
  1107.      * write boot sector to media.
  1108.      *
  1109.       *    512 bytes/sector
  1110.      *    2 or 4 sectors/cluster (partition > 16Mb has 4 spc)
  1111.      *    1 reserved sector (for boot)
  1112.      *    2 FATs
  1113.      *    ... dir slots
  1114.      *    ... # sectors
  1115.      *    F8 means media is a hard disk
  1116.      *    ... FAT size
  1117.      *
  1118.      */
  1119.      
  1120.     /* Make a clean boot sector */
  1121.     fillbuf(buf, bps, 0L);
  1122.     bs = (BOOT *)buf;
  1123.         
  1124.  
  1125.     /* bytes per sector */
  1126.     iw((UWORD *)&bs->b_bps[0], (UWORD)bps);
  1127.     
  1128.     /* sectors per cluster */
  1129.     bs->b_spc = SPC;
  1130.         
  1131.     /* number of reserved sectors */
  1132.     iw((UWORD *)&bs->b_res[0], (UWORD)1);
  1133.     
  1134.     /* number of FATs */
  1135.     bs->b_nfats = 2;
  1136.     
  1137.  
  1138.     /*
  1139.      * Compute root directory size
  1140.      * 256 entries, plus fudge on devs > 10Mb
  1141.      */
  1142.     if (pinfo->p_siz < 0x5000L) ndirs = NUMEN;
  1143.     else ndirs = nsect / 80;    /* 1 dir entry per 80 sectors */
  1144.     /* round to nearest sector */
  1145.     ndirs = (ndirs + ((UWORD)bps/BPDIR - 1)) & ~((UWORD)bps/BPDIR - 1);    
  1146.     iw((UWORD *)&bs->b_ndirs[0], (UWORD)ndirs);
  1147.     
  1148.     /* number of sectors on media (partition) */
  1149.     iw((UWORD *)&bs->b_nsects[0], (UWORD)nsect);
  1150.  
  1151.     /* media descriptor */
  1152.     bs->b_media = 0xf8;
  1153.  
  1154.     /*--------------------------------------------------------------*
  1155.      * Compute FAT size                        *
  1156.      *                                *
  1157.      * Num entries to map the entire partition            *
  1158.      *    = partition's size in clusters                *
  1159.      *    = partition's size in sectors / spc            *
  1160.      *                                *
  1161.      * Num entries in FAT                        *
  1162.      *    = Num entries to map partition + reserved entries    *
  1163.      *    = (partition's size in sectors / spc) + 2        *
  1164.      *                                *
  1165.      * Num sectors FAT occupies                    *
  1166.      *    = Num entries in FAT / Num entries of FAT per sector    *
  1167.      *    = Num entries in FAT / (512 / 2)    <16-bit FAT>    *
  1168.      *    = ((partition's size in sectors / spc) + 2) / 256 + 1    *
  1169.      *                        <+1 to round up>    *
  1170.      *--------------------------------------------------------------*/
  1171.     fatsiz = ((((nsect / bs->b_spc) + 2) * 2) / bps) + 1;
  1172.     iw((UWORD *)&bs->b_spf[0], (UWORD)fatsiz);
  1173.  
  1174.     /* write the serial number to the bs */ 
  1175.     Protobt(bs, 0x01000000, -1, -1);
  1176.  
  1177.     /*
  1178.      * Write partition's boot sector
  1179.      */
  1180.     forcesum((UWORD *)buf, (UWORD)0);    /* force image checksum */
  1181.     if ((ret = wrsects(physdev,(UWORD)ratio,buf,(SECTOR)pinfo->p_st))!= OK) {
  1182.         if (tsterr(ret) != OK)
  1183.             err(bootwrit);
  1184.         return ERROR;
  1185.     }
  1186.  
  1187.     /*
  1188.      * Zero the partition
  1189.      */
  1190.     if ((ret = zerosect(physdev, (SECTOR)(pinfo->p_st+ratio),
  1191.              ((UWORD)((fatsiz*2 + ndirs*BPDIR/bps) * ratio)))) != OK) {
  1192.         if (tsterr(ret) != OK)
  1193.             err(hdrwrite);
  1194.         return ERROR;
  1195.     }
  1196.              
  1197.     /*
  1198.      * Make first 2 entries in FATs more IBM-like.
  1199.      */
  1200.     if ((ret = rdsects(physdev,(UWORD)ratio,buf,
  1201.                         (SECTOR)(pinfo->p_st+ratio)))!= 0){
  1202.         if (tsterr(ret) != OK)
  1203.             err(fatread);
  1204.         return ERROR;
  1205.     }
  1206.     *(UWORD *)&buf[0] = 0xf8ff;
  1207.     *(UWORD *)&buf[2] = 0xffff;
  1208.     if ((ret = wrsects(physdev,(UWORD)ratio,
  1209.                         buf,(SECTOR)(pinfo->p_st+ratio)))!= 0 ||
  1210.         (ret = wrsects(physdev,(UWORD)ratio,buf,
  1211.                         (SECTOR)(pinfo->p_st+ratio+fatsiz*ratio)))
  1212.         != 0) {
  1213.         if (tsterr(ret) != OK)
  1214.             err(fatwrite);
  1215.         return ERROR;
  1216.     }
  1217.  
  1218.     /*
  1219.      * Mark bad sectors recorded in the BSL into the FATs.
  1220.      * Calculating parameters:
  1221.      *    ldev - from physdev and i.
  1222.      *    fat0 - always equals 1.
  1223.      *    fatsiz - calculated above.
  1224.      *    data - starts after the boot sector, 2 FATs and rootdir.
  1225.      */
  1226.  
  1227.         if (bslsiz > 0) {
  1228.             if ((ldev = phys2log(physdev, i)) == ERROR)
  1229.                 return parterr(physdev);
  1230.             data = (SECTOR)1 + (SECTOR)(fatsiz*2) + (SECTOR)(ndirs*BPDIR/bps);
  1231.             bsl2fat(ldev, (SECTOR)ratio, (UWORD)(fatsiz*ratio), 
  1232.                                                 data*ratio, MEDIA);
  1233.         }
  1234.         if (buf > 0) Mfree((long)buf);
  1235.     }
  1236.     return OK;
  1237. }
  1238.  
  1239.  
  1240.  
  1241.  
  1242. /*
  1243.  * Handle [ZERO] item.
  1244.  *
  1245.  */
  1246. dodizero()
  1247. {
  1248.     int ldev, ret;
  1249.     char *seldev = "X";
  1250.     int i; 
  1251.  
  1252.     zwarning[ZWOK].ob_state = NORMAL;
  1253.     zwarning[ZWCN].ob_state = NORMAL;
  1254.     if (execform(zwarning) != ZWOK)
  1255.     return BAILOUT;
  1256.     if (showmany)    err(manyldev);
  1257.  
  1258.     if ((ldev = glogdev()) < 0) return BAILOUT;
  1259.  
  1260.     /* Find out if logical device has assumed parameters */
  1261.     if (chkparm(ldev) != OK) {
  1262.         wronparm[WRONOK].ob_state = NORMAL;
  1263.     execform(wronparm);
  1264.     return ERROR;
  1265.     }
  1266.         
  1267.     *seldev = ldev;
  1268.     (zerofnl[ZDRV].ob_spec)->te_ptext = seldev;
  1269.     strcat((zerofnl[ZDRV].ob_spec)->te_ptext, ":");
  1270.     zerofnl[ZYES].ob_state = NORMAL;
  1271.     zerofnl[ZNO].ob_state = NORMAL;
  1272.     if (execform(zerofnl) != ZYES)  return BAILOUT;
  1273.  
  1274.     dsplymsg(zeromsg);
  1275.     if (zero(ldev) == OK) {
  1276.     if (!rebootp) {
  1277.         for (i = 0; i < 10; i++) {
  1278.         if (!mediach(ldev-'A')) break;
  1279.         }
  1280.         if (i == 10) {
  1281.             rebootp = 1;
  1282.         err(mdach);
  1283.             }
  1284.     }
  1285.     }
  1286.     erasemsg();
  1287. }
  1288.  
  1289.  
  1290. /*
  1291.  * Handle [MARKBAD] item.
  1292.  *
  1293.  */
  1294. dodimark()
  1295. {
  1296.     int ldev, ret;
  1297.     int i;
  1298.  
  1299.     mwarning[MWARNOK].ob_state = NORMAL;
  1300.     mwarning[MWARNCN].ob_state = NORMAL;
  1301.     if (execform(mwarning) == MWARNCN)
  1302.         return BAILOUT;
  1303.     if (showmany)    err(manyldev);
  1304.  
  1305.     if ((ldev = glogdev()) < 0)
  1306.         return BAILOUT;
  1307.         
  1308.     /* Find out if logical device has assumed parameters */
  1309.     if (chkparm(ldev) != OK) {
  1310.         wronparm[WRONOK].ob_state = NORMAL;
  1311.     execform(wronparm);
  1312.     return ERROR;
  1313.     }
  1314.          
  1315.     dsplymsg(lmrkmsg);
  1316.     if (markbad(ldev) != OK) {
  1317.         erasemsg();
  1318.     } else {
  1319.         if (!rebootp) {
  1320.         for (i = 0; i < 10; i++) {
  1321.         if (!mediach(ldev-'A')) break;
  1322.         }
  1323.         if (i == 10) {
  1324.             rebootp = 1;
  1325.         err(mdach);
  1326.             }
  1327.         }
  1328.     }
  1329. }
  1330.  
  1331.  
  1332. /*
  1333.  * Map from button in ship dial.
  1334.  */
  1335. int sdev[] = {
  1336.     SDEV0, SDEV1, SDEV2, SDEV3,
  1337.     SDEV4, SDEV5, SDEV6, SDEV7
  1338. };
  1339.  
  1340. /*
  1341.  * Ship selected devices.
  1342.  */
  1343. dodiship()
  1344. {
  1345.   int i, seldev[24], selected=0;
  1346.   int j, endup, index=0, unit=8, ret;
  1347.   
  1348.     /* Set up the dialog box for SCSI or ACSI driver selection */
  1349.     typedial[SCSIYES].ob_state = NORMAL;
  1350.     typedial[ACSIYES].ob_state = NORMAL;
  1351.     typedial[IDEYES].ob_state = NORMAL;
  1352.     /* check which type of unit was selected */
  1353.     if ((!ttscsi) && (noacsi))    { /* don't need select */
  1354.         index = 16;
  1355.         unit = 2;
  1356.     } else if ((!ttscsi) && (!atexst))    { /* don't need select */
  1357.         ;
  1358.     } else if ((!atexst) && (noacsi))    { /* don't need select */
  1359.         index = 8;
  1360.     } else {
  1361.         if (!ttscsi)    {
  1362.             typedial[SCSIYES].ob_state = DISABLED;
  1363.         } else if (!atexst)    {
  1364.             typedial[IDEYES].ob_state = DISABLED;
  1365.         } else if (noacsi)    {
  1366.             typedial[ACSIYES].ob_state = DISABLED;
  1367.         }
  1368.         if ((ret = execform(typedial)) == SCSIYES)    {
  1369.             index = 8;
  1370.         } else if (ret == IDEYES)    {
  1371.             index = 16;
  1372.             unit = 2;
  1373.         }
  1374.     } 
  1375.     
  1376.   /* Throw up generic shipping warning. */
  1377.   shipdial[SWARNCN].ob_state = NORMAL;
  1378.   shipdial[SWARNOK].ob_state = NORMAL;
  1379.   if (execform(shipdial) != SWARNOK) return BAILOUT;
  1380.   
  1381.   /* Device(s) selected? */
  1382.   shipdev[SDEVOK].ob_state = NORMAL;
  1383.   shipdev[SDEVCN].ob_state = NORMAL;
  1384.   for(i = 0; i < 8; i++)     /* indicate what's alive */
  1385.         shipdev[sdev[i]].ob_state = DISABLED;
  1386.   endup = index + unit;
  1387.   for(i = index, j = 0; i < endup; i++, j++)     /* indicate what's alive */
  1388.         if (livedevs[i])
  1389.             shipdev[sdev[j]].ob_state = NORMAL | SHADOWED;
  1390.   
  1391.   if (execform(shipdev) != SDEVOK)
  1392.       return BAILOUT;
  1393.       
  1394.   for(i = 0; i < 8; i++) {    /* search for selected unit */
  1395.       if (shipdev[sdev[i]].ob_state & SELECTED) {
  1396.           seldev[i+index] = 1;
  1397.           selected++;
  1398.       } else {
  1399.             seldev[i+index] = 0;
  1400.       }
  1401.   }
  1402.   
  1403.   if (!selected) return BAILOUT;    /* nothing is selected */
  1404.   
  1405.   /* Throw up final shipping warning. */
  1406.   shipfnl[SFNLCN].ob_state = NORMAL;
  1407.   shipfnl[SFNLOK].ob_state = NORMAL;
  1408.   if (execform(shipfnl) != SFNLOK) return BAILOUT;
  1409.   
  1410.   /* For REAL!!! */
  1411.   /* Ship selected devices */
  1412.   for (i = 0; i < MAXPHYSDEV; i++) {
  1413.       if (seldev[i])
  1414.           ship(i);
  1415.   }
  1416.   
  1417.   /* Put out final message about turning off hard disks */
  1418.   scommand[TRNOFFOK].ob_state = NORMAL;
  1419.   execform(scommand);
  1420. }
  1421.  
  1422.  
  1423.  
  1424. /*
  1425.  * Translate unit number to tree index.
  1426.  *
  1427.  */
  1428. static int physxlat[] = {
  1429.     UNIT0, UNIT1, UNIT2, UNIT3,
  1430.     UNIT4, UNIT5, UNIT6, UNIT7
  1431. };
  1432.  
  1433.  
  1434. /*
  1435.  * Get physical device#,
  1436.  * return devno or -1.
  1437.  *
  1438.  */
  1439. gphysdev()
  1440. {
  1441.     int i, j, endup, start, index=0;
  1442.     int ret, unit=8;
  1443.  
  1444.     /* Set up the dialog box for SCSI or ACSI or IDE-AT driver selection */
  1445. redogphy:
  1446.     typedial[SCSIYES].ob_state = NORMAL;
  1447.     typedial[ACSIYES].ob_state = NORMAL;
  1448.     typedial[IDEYES].ob_state = NORMAL;
  1449.     /* check which type of unit was selected */
  1450.     if ((!ttscsi) && (noacsi))    { /* don't need select */
  1451.         index = 16;
  1452.         unit = 2;
  1453.     } else if ((!ttscsi) && (!atexst))    { /* don't need select */
  1454.         ;
  1455.     } else if ((!atexst) && (noacsi))    { /* don't need select */
  1456.         index = 8;
  1457.     } else {
  1458.         if (!ttscsi)    {
  1459.             typedial[SCSIYES].ob_state = DISABLED;
  1460.         } else if (!atexst)    {
  1461.             typedial[IDEYES].ob_state = DISABLED;
  1462.         } else if (noacsi)    {
  1463.             typedial[ACSIYES].ob_state = DISABLED;
  1464.         }
  1465.         if ((ret = execform(typedial)) == SCSIYES)    {
  1466.             index = 8;
  1467.         } else if (ret == IDEYES)    {
  1468.             index = 16;
  1469.             unit = 2;
  1470.         }
  1471.     } 
  1472.     /*
  1473.      * Clean up and exec object;
  1474.      * shadow devs we KNOW are there.
  1475.      */
  1476.     physdial[PHYSOK].ob_state = NORMAL;
  1477.     physdial[PHYSCN].ob_state = NORMAL;
  1478.     
  1479.     if (tformat == TRUE) {
  1480.         start = 1;        /* start initializing at unit 0 */
  1481.         physdial[physxlat[0]].ob_state = NORMAL;
  1482.     } else {
  1483.         start = 0;        /* start initializing at unit 1 */
  1484.     }
  1485.     
  1486.     endup = index + unit;
  1487.     for (i = start; i < 8; ++i)
  1488.         physdial[physxlat[i]].ob_state = DISABLED;
  1489.     /*
  1490.     if (ttscsi)             the hard drive is a SCSI drive 
  1491.         physdial[physxlat[8]].ob_state = NORMAL;
  1492.     */
  1493.     for (i = index, j = 0; i < endup; ++i, j++)
  1494.         if (livedevs[i])
  1495.             physdial[physxlat[j]].ob_state = NORMAL | SHADOWED;
  1496.  
  1497.     if (execform(physdial) != PHYSOK)
  1498.         return ERROR;
  1499.      
  1500.     /* search for the selected unit */
  1501.     for (i = 0; i < unit; ++i)
  1502.         if (physdial[physxlat[i]].ob_state & SELECTED)    {
  1503.             if (livedevs[index+i])
  1504.                 return(index+i);
  1505.             else    {    
  1506.                 form_alart(1, nodev);
  1507.                 goto redogphy;
  1508.             }
  1509.         }
  1510.  
  1511.  
  1512.     return ERROR;            /* if no object selected */
  1513. }
  1514.  
  1515.  
  1516. /*
  1517.  * Translate from logical device number
  1518.  * to object number in logical device
  1519.  * dialouge box.
  1520.  */
  1521. int logxlat[] = {
  1522.     CCOLON, DCOLON, ECOLON, FCOLON,
  1523.     GCOLON, HCOLON, ICOLON, JCOLON,
  1524.     KCOLON, LCOLON, MCOLON, NCOLON,
  1525.     OCOLON, PCOLON
  1526. };
  1527.  
  1528.  
  1529. /*
  1530.  * Get logical device,
  1531.  * return 'C'...'P'
  1532.  * or -1.
  1533.  *
  1534.  */
  1535. glogdev()
  1536. {
  1537.     int i, flg;
  1538.  
  1539.     /*
  1540.      * Setup tree; selectively enable drive buttons
  1541.      * and so on.
  1542.      */
  1543.     logdial[LOGOK].ob_state = NORMAL;
  1544.     logdial[LOGCN].ob_state = NORMAL;
  1545.     for (i = 0; i < MAXLOGDEVS; ++i) {
  1546.     if (logmap[i].lm_physdev < 0)
  1547.         flg = DISABLED;
  1548.         else flg = NORMAL;
  1549.     logdial[logxlat[i]].ob_state = flg;
  1550.     }
  1551.  
  1552.     if (execform(logdial) != LOGOK) return -1;
  1553.  
  1554.     for (i = 0; i < MAXLOGDEVS; ++i)
  1555.     if (logdial[logxlat[i]].ob_state & SELECTED)
  1556.         return i + 'C';
  1557.  
  1558.     return -1;
  1559. }
  1560.  
  1561.  
  1562. /*
  1563.  * Open virtual workstation.
  1564.  *
  1565.  */
  1566. open_vwork()
  1567. {
  1568.     int i;
  1569.  
  1570.     for (i = 0; i < 10;)
  1571.     work_in[i++] = 1;
  1572.     work_in[10] = 2;
  1573.     handle = phys_handle;
  1574.     v_opnvwk(work_in, &handle, work_out);
  1575. }
  1576.  
  1577.  
  1578. /*
  1579.  * Find and redraw all clipping rectangles
  1580.  *
  1581.  */
  1582. do_redraw(xc, yc, wc, hc)
  1583. int xc, yc, wc, hc;
  1584. {
  1585.     GRECT t1, t2;
  1586.     int temp[4];
  1587.  
  1588.     hide_mouse();
  1589.     t2.g_x=xc;
  1590.     t2.g_y=yc;
  1591.     t2.g_w=wc;
  1592.     t2.g_h=hc;
  1593.     vsf_interior(handle, 1);
  1594.     vsf_color(handle, 0);
  1595.     wind_get(wi_handle, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  1596.     while (t1.g_w && t1.g_h) {
  1597.     if (rc_intersect(&t2, &t1)) {
  1598.         set_clip(t1.g_x, t1.g_y, t1.g_w, t1.g_h);
  1599.         temp[0] = xwork;
  1600.         temp[1] = ywork;
  1601.         temp[2] = xwork + wwork - 1;
  1602.         temp[3] = ywork + hwork - 1;
  1603.         v_bar(handle, temp);
  1604.     }
  1605.     wind_get(wi_handle, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  1606.     }
  1607.  
  1608.     show_mouse();
  1609. }
  1610.  
  1611.  
  1612. /*
  1613.  * Hide the mouse.
  1614.  *
  1615.  */
  1616. hide_mouse()
  1617. {
  1618.     if (!hidden) {
  1619.     graf_mouse(M_OFF, 0L);
  1620.     hidden = TRUE;
  1621.     }
  1622. }
  1623.  
  1624.  
  1625. /*
  1626.  * Show the mouse.
  1627.  *
  1628.  */
  1629. show_mouse() 
  1630. {
  1631.     if (hidden) {
  1632.     graf_mouse(M_ON, 0L);
  1633.     hidden = FALSE;
  1634.     }
  1635. }
  1636.  
  1637.  
  1638. /*
  1639.  * Set clipping rectangle.
  1640.  *
  1641.  */
  1642. set_clip(x, y, w, h)
  1643. int x, y, w, h;
  1644. {
  1645.     int clip[4];
  1646.  
  1647.     clip[0] = x;
  1648.     clip[1] = y;
  1649.     clip[2] = x + w;
  1650.     clip[3] = y + h;
  1651.     vs_clip(handle, 1, clip);
  1652. }
  1653.  
  1654.  
  1655. /*
  1656.  * "Execute" form,
  1657.  * return thingy that caused the exit.
  1658.  *
  1659.  */
  1660. execform(tree)
  1661. OBJECT tree[];
  1662. {
  1663.     int thingy;
  1664.  
  1665.     ARROW_MOUSE;
  1666.     dsplymsg(tree);
  1667.     thingy = form_do(tree, 0);
  1668.     erasemsg();
  1669.     BEE_MOUSE;
  1670.     return thingy;
  1671. }
  1672.  
  1673.  
  1674. /*
  1675.  *  Display a dialogue box on the screen.
  1676.  *    Input:
  1677.  *        tree - object tree for dialogue box to be displayed.
  1678.  *    Output:
  1679.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  1680.  */
  1681. dsplymsg(tree)
  1682. OBJECT *tree;
  1683. {
  1684.     form_center(tree,&lx, &ly, &formw, &formh);
  1685.  
  1686.     /*
  1687.     sx = lx + formw / 2;
  1688.     sy = ly + formh / 2;
  1689.     */
  1690.     
  1691.     form_dial(1, 0, 0, 0, 0, lx, ly, formw, formh);
  1692.     objc_draw(tree, 0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1693. }
  1694.  
  1695.  
  1696. /*
  1697.  *  Erase a dialogue box from the screen.
  1698.  *    Input:
  1699.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  1700.  */
  1701. erasemsg()
  1702. {
  1703.     form_dial(3, 0, 0, 0, 0, lx, ly, formw, formh);
  1704. }
  1705.  
  1706.  
  1707.  
  1708. /*
  1709.  *  Make a long (4-byte) random.
  1710.  */ 
  1711. long
  1712. longrandom()
  1713. {
  1714.     long pattern;
  1715.     
  1716.     pattern = Random();
  1717.     pattern <<= 16;
  1718.     pattern ^= Random();
  1719.     
  1720.     return (pattern);
  1721. }
  1722.  
  1723. changeid(part)
  1724. PART *part;
  1725. {
  1726.     int i;
  1727.     long psiz;
  1728.  
  1729.     for(i = 0; i < npart; i++)    {
  1730.         if (i == ext)    continue;
  1731.         if (!(part[i].p_flg & P_EXISTS)) return OK;
  1732.         if (i > 3)    {
  1733.             psiz = part[i].p_siz - ROOTSECT;
  1734.         } else {
  1735.             psiz = part[i].p_siz;
  1736.         }
  1737.         if (psiz < MB16)    {
  1738.             part[i].p_id[0] = 'G';
  1739.             part[i].p_id[1] = 'E';
  1740.             part[i].p_id[2] = 'M';
  1741.         } else {
  1742.             part[i].p_id[0] = 'B';
  1743.             part[i].p_id[1] = 'G';
  1744.             part[i].p_id[2] = 'M';
  1745.         }
  1746.     }
  1747. }
  1748.  
  1749.